//$Id: BuildingManager.java 239 2010-11-08 11:48:27Z edwardchuajh $

package builders;

import java.io.BufferedReader;
import java.io.FileReader;

/**
 * this class will manage all the buildings in the game
 * 
 * @author Vincent
 *
 */
public class BuildingManager {

	public static final int TOTAL_NUMBER_OF_BUILDING_IN_GAME = 6;
	private Building[] manager = new Building[TOTAL_NUMBER_OF_BUILDING_IN_GAME];
	private int totalNumberOfBuildingsAvailable;
	private static String curDir = System.getProperty("user.dir");

	/**
	 * This is the default constructor of the BuildingManager class.
	 */
	public BuildingManager() {
		this("building.txt");
	}

	/**
	 * This is the constructor of the BuildingManager class which allows the user to specify the file name from which the BuildingManager will load the data of the buildings.
	 * 
	 * the format of the .txt file is as follows:
	 * building name
	 * building image file name
	 * building points
	 * number of building available
	 * number of building requirement
	 * -resource
	 * -resource amount
	 * 
	 * the last two data (resource and resource amount) must come as a set
	 * also the number of such set of data must equal to the number specify by number of building requirement
	 * 
	 * @param fileName	specify the name of the file from which the BuildingManager will load the data of the buildings 
	 */
	public BuildingManager(String fileName) {
		try {
			FileReader reader = new FileReader(curDir + "\\src\\builders\\" + fileName);
			BufferedReader File = new BufferedReader(reader);

			for (int i = 0; i < TOTAL_NUMBER_OF_BUILDING_IN_GAME; i++) {

				String buildingName = File.readLine(); 
				String buildingImageFile = File.readLine(); 
				String buildingPoints = File.readLine();
				String numberOfBuildingAvailable = File.readLine();
				String stringNumberOfBuildingRequirement = File.readLine();
				
				int numberOfBuildingRequirement = Integer.valueOf(stringNumberOfBuildingRequirement);
				BuildingRequirement[] buildingRequirement = createBuildingRequirementArray(numberOfBuildingRequirement);

				int resourcesAdded = 0; 
				
				while (resourcesAdded <  numberOfBuildingRequirement){

					String resource = File.readLine(); 
					String resourceAmount = File.readLine(); 

					setResource(buildingRequirement, resourcesAdded, resource, resourceAmount);
					resourcesAdded++;
				}
				
				Building newBuilding = new Building(buildingName, buildingImageFile, buildingPoints, numberOfBuildingAvailable, buildingRequirement);
				
				manager[i] = newBuilding;

			}
		} catch (Exception e) {
			System.err.println(e);
		}
	}
	
	/**
	 * @param numberOfBuildingRequirement	specify the number of resources the player need to build this building
	 * @return								an array of BuildingRequirement of size as specified by the input parameter
	 */
	public BuildingRequirement[] createBuildingRequirementArray(int numberOfBuildingRequirement) {
		return new BuildingRequirement[numberOfBuildingRequirement];
	}

	/**
	 * @param buildingRequirement 		the BuildingRequirement[] with which the BuildingRequirement is going to be added into
	 * @param resourcesAdded 			specify the number of BuildingRequirement that has been added to BuildingRequirement[]
	 * @param stringResource			specify the resource required to build the building
	 * @param stringResourceAmount		specify the amount of resource required to build the building
	 */
	public void setResource(BuildingRequirement[] buildingRequirement, int resourcesAdded, String stringResource, String stringResourceAmount) {

		Player.Resource resource = searchResource(stringResource);
		int resourceAmount = Integer.valueOf(stringResourceAmount);

		BuildingRequirement resourceRequirement = new BuildingRequirement(resource, resourceAmount);

		buildingRequirement[resourcesAdded] = resourceRequirement;
		resourcesAdded++;
	}

	/**
	 * This method will match the String input to the name of a Player.Resource and return the matched resource.
	 * 
	 * @param stringResource	the String input from the method setResource
	 * @return					the Player.Resource that matches with the String input
	 */
	public Player.Resource searchResource(String stringResource) {
		Player.Resource requestedResource = null;
		for (Player.Resource resource : Player.Resource.values()){
			if (resource.toString().equals(stringResource)){
				requestedResource = resource;
			}
		}
		return requestedResource;
	}

	/**
	 * @return	the total number of buildings left in the game
	 */
	public int getTotalNumberOfBuildingsAvailable(){
		totalNumberOfBuildingsAvailable = 0;
		for (int i = 0; i < TOTAL_NUMBER_OF_BUILDING_IN_GAME; i++){
			totalNumberOfBuildingsAvailable += manager[i].getNumberOfBuildingsAvailable();
		}
		return totalNumberOfBuildingsAvailable;
	}

	/**
	 * @param buildingName	the string that will be used to get the building which the string corresponds to
	 * @return				the building which the input string corresponds to
	 */
	public Building stringToBuilding(String buildingName){
		Building requestedBuilding = null;
		for (Building building: manager){
			if (building.getName().equals(buildingName)){
				requestedBuilding = building;
			}
		}
		return requestedBuilding;
	}
	
	/**
	 * @return	the array of buildings managed by BuildingManager
	 */
	public Building[] getManager(){
		return manager;
	}
}
